#include <mFS/FsTypes.h>
#include <mFS/mConfig.h>
#include <Utils/Mem.h>
#include <Utils/StructDef.h>
#include <apdu/APDUParse.h>
#include <apdu/SwCode.h>
#include <apdu/xAuthAP.h>
#include <cmd/CMDxAuth.h>


void CMDxAuth_Create(void)
{
	ApduCmd *pCmd;
	UINT16 nRet;

	pCmd = APDU_GetCmd();

	if(pCmd->CLA != 0xC0)
	{
		APDU_SetRespond(0, ISOSW_CLA_ERROR);
		return ;
	}

	if(pCmd->LC != 2 + 1 + 1 + 1 + 1)
	{
		APDU_SetRespond(0, ISOSW_LC_ERROR);
		return ;
	}

	if(pCmd->P2 > 1)
	{
		APDU_SetRespond(0, ISOSW_P1P2_ERROR);
		return ;
	}

	nRet = xAuthAP_Create(pCmd->pData, pCmd->P1, !pCmd->P2);
	
	APDU_SetRespond(0, nRet);

	return ;	
}

void CMDxAuth_Enroll(void)
{
	ApduCmd *pCmd;
	ApduRsp *pRsp;
	UINT16 nLen;
	UINT16 nRet;

	pCmd = APDU_GetCmd();
	pRsp = APDU_GetRsp();

	if(pCmd->CLA != 0xC0)
	{
		APDU_SetRespond(0, ISOSW_CLA_ERROR);
		return ;
	}

	if(pCmd->LC != 2 + 1)
	{
		APDU_SetRespond(0, ISOSW_LC_ERROR);
		return ;
	}

	if(pCmd->P1 > 1 || pCmd->P2 > 1)
	{
		APDU_SetRespond(0, ISOSW_P1P2_ERROR);
		return ;
	}

	nRet = xAuthAP_Enroll(pCmd->pData, pCmd->P1, pCmd->P2, pRsp->pData, &nLen);
	
	APDU_SetRespond(nLen, nRet);

	return ;	
}

void CMDxAuth_Verify(void)
{
	ApduCmd *pCmd;
	ApduRsp *pRsp;
	UINT16 nLen;
	UINT16 nRet;

	pCmd = APDU_GetCmd();
	pRsp = APDU_GetRsp();

	if(pCmd->CLA != 0xC0)
	{
		APDU_SetRespond(0, ISOSW_CLA_ERROR);
		return ;
	}

	if(pCmd->LC != 2 + 1)
	{
		APDU_SetRespond(0, ISOSW_LC_ERROR);
		return ;
	}

	if(pCmd->P1 > 1 || pCmd->P2 > 1)
	{
		APDU_SetRespond(0, ISOSW_P1P2_ERROR);
		return ;
	}

	nRet = xAuthAP_Verify(pCmd->pData, pCmd->P1, pCmd->P2, pRsp->pData, &nLen);
	
	APDU_SetRespond(nLen, nRet);

	return ;
}

void CMDxAuth_VerifyEx1(void)
{
	ApduCmd *pCmd;
	ApduRsp *pRsp;
	UINT16 nLen;
	UINT16 nRet;

	pCmd = APDU_GetCmd();
	pRsp = APDU_GetRsp();

	if(pCmd->CLA != 0xC0)
	{
		APDU_SetRespond(0, ISOSW_CLA_ERROR);
		return ;
	}

	if((pCmd->P1 == 1 && pCmd->LC <= 2 + 1) ||
	   (pCmd->P1 == 0 && pCmd->LC < 2))
	{
		APDU_SetRespond(0, ISOSW_LC_ERROR);
		return ;
	}

	if(pCmd->P1 > 1 || pCmd->P2 > 1)
	{
		APDU_SetRespond(0, ISOSW_P1P2_ERROR);
		return ;
	}

	nRet = xAuthAP_VerifyEx1(pCmd->pData, pCmd->P1, pCmd->P2, pRsp->pData, &nLen);
	
	APDU_SetRespond(nLen, nRet);

	return ;
}

void CMDxAuth_VerifyEx2(void)
{
	ApduCmd *pCmd;
	ApduRsp *pRsp;
	UINT16 nLen;
	UINT16 nRet;

	pCmd = APDU_GetCmd();
	pRsp = APDU_GetRsp();

	if(pCmd->CLA != 0xC0)
	{
		APDU_SetRespond(0, ISOSW_CLA_ERROR);
		return ;
	}

	if(pCmd->LC != 2 + 2 + 1)
	{
		APDU_SetRespond(0, ISOSW_LC_ERROR);
		return ;
	}

	if(pCmd->P1 > 1 || pCmd->P2 > 1)
	{
		APDU_SetRespond(0, ISOSW_P1P2_ERROR);
		return ;
	}

	nRet = xAuthAP_VerifyEx2(pCmd->pData, pCmd->P1, pCmd->P2, pRsp->pData, &nLen);
	
	APDU_SetRespond(nLen, nRet);

	return ;
}

void CMDxAuth_Delete(void)
{
	ApduCmd *pCmd;
	UINT16 nRet;

	pCmd = APDU_GetCmd();

	if(pCmd->CLA != 0xC0)
	{
		APDU_SetRespond(0, ISOSW_CLA_ERROR);
		return ;
	}

	if(pCmd->LC != 2)
	{
		APDU_SetRespond(0, ISOSW_LC_ERROR);
		return ;
	}

	if(pCmd->P1 == 0 || pCmd->P2 > 1)
	{
		APDU_SetRespond(0, ISOSW_P1P2_ERROR);
		return ;
	}

	nRet = xAuthAP_Delete(pCmd->pData, pCmd->P2, pCmd->P1);
	
	APDU_SetRespond(0, nRet);

	return ;
}

void CMDxAuth_GetInfo(void)
{
	ApduCmd *pCmd;
	ApduRsp *pRsp;
	UINT16 nLen;
	UINT16 nRet;

	pCmd = APDU_GetCmd();
	pRsp = APDU_GetRsp();

	if(pCmd->CLA != 0xC0)
	{
		APDU_SetRespond(0, ISOSW_CLA_ERROR);
		return ;
	}

	if(pCmd->LC != 2)
	{
		APDU_SetRespond(0, ISOSW_LC_ERROR);
		return ;
	}

	nRet = xAuthAP_GetInfo(pCmd->pData, pCmd->P1, pCmd->P2, pRsp->pData, &nLen);
	
	APDU_SetRespond(nLen, nRet);

	return ;
}

void CMDxAuth_SetConfig(void)
{
	ApduCmd *pCmd;
	UINT16 nRet;

	pCmd = APDU_GetCmd();

	if(pCmd->CLA != 0xC0)
	{
		APDU_SetRespond(0, ISOSW_CLA_ERROR);
		return ;
	}

	if(pCmd->P2 > 1)
	{
		APDU_SetRespond(0, ISOSW_P1P2_ERROR);
		return ;
	}

	nRet = xAuthAP_SetConfig(pCmd->pData, pCmd->P1, pCmd->P2);
	
	APDU_SetRespond(0, nRet);

	return ;
}

void CMDxAuth_EnrollVerifyCancel(void)
{
	ApduCmd *pCmd;
	UINT16 nRet;

	pCmd = APDU_GetCmd();

	if(pCmd->CLA != 0xC0)
	{
		APDU_SetRespond(0, ISOSW_CLA_ERROR);
		return ;
	}

	nRet = xAuthAP_EnrollVerifyCancel(pCmd->pData, pCmd->LC);
	
	APDU_SetRespond(0, nRet);

	return ;
}
